#pragma once
#include "DXAMLCommon.h"
#include "CSurfaceImageSource.h"

class HWTextureManager;

class IVirtualSurfaceImageSourceCallbacks
{
public: 
	virtual HRESULT UpdatesNeeded() = 0;
};


class CVirtualSurfaceImageSource :
	public CSurfaceImageSource
{

protected: 
	virtual HRESULT PreUpdateVirtual(const struct XRECT_WH * pUpdateRect);
	virtual HRESULT EnsureTiles(HWTextureManager * __formal);

public: 
	CVirtualSurfaceImageSource(CCoreServices * pCore);
	virtual ~CVirtualSurfaceImageSource();
	HRESULT Create(XINT32 width, XINT32 height, XBOOL isOpaque);
	static HRESULT Create(CDependencyObject * * ppObject, CREATEPARAMETERS * pCreate);
	virtual XUINT32 GetTypeIndex() const;
	HRESULT Invalidate(struct XRECT_WH invalidateRect);
	HRESULT GetUpdateRectCount(unsigned long * pCount);
	HRESULT GetUpdateRects(struct XRECT_WH * pUpdates, unsigned long count);
	HRESULT CalculateBounds(const struct XRECTF_RB * pWindowBounds);
	HRESULT Resize(XINT32 newWidth, XINT32 newHeight);
	HRESULT RegisterCallbacks(IVirtualSurfaceImageSourceCallbacks * pCallbacks);
	HRESULT PreRender(const struct XRECTF_RB * pWindowBounds, XBOOL * pWantAdditionalFrame);
	void GetVisibleBounds(struct XRECT_RB * pBounds);
	virtual HRESULT HandleLostResources(SurfaceCache * pSurfaceCache, XBOOL * pWasDeviceLost);
	HRESULT UpdateStandbyLists(struct VirtualSurfaceImageSourceStandbyLists * pStandbyLists);
	void FreeTile(struct CTiledSurface::Tile * pTile);
protected: 
	virtual XBOOL SupportsFlipping();
	virtual XBOOL UsePermanentAtlas();
	virtual XBOOL IsTileCompletelyFilled(const struct CTiledSurface::Tile * pTile);
	virtual void SetInteropUsage();
private: 
	static const XUINT32 sc_oldTileTime;
	IVirtualSurfaceImageSourceCallbacks * m_pCallbacks;
	HRESULT CalculateNeededUpdates();
	HRESULT RaiseCallbacks();
	HRESULT RequestTickForUpdatesNeeded();
	static void CalculateDesiredBounds(struct XRECT_RB * pDesired, struct XRECT_RB * pHighPriorityDesired, const struct XRECT_RB * pVisible, XUINT32 motionFlags);
	XBOOL TileInsideDesiredBounds(const struct CTiledSurface::Tile * pTile);
	void AssertValidRegion();
	xvector<XRECT_WH> m_neededUpdates;
	struct XRECT_RB m_visibleBounds;
	struct XRECT_RB m_highPriorityDesiredBounds;
	struct XRECT_RB m_desiredBounds;
	XUINT32 m_motionFlags;
	struct IPALRegion * m_pValidRegion;
	XBOOL m_neededUpdatesValid:1;
	XBOOL m_onGlobalVSISList:1;
	XBOOL m_wantHighPriorityUpdates:1;

};